{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "fcb3ad26",
   "metadata": {},
   "source": [
    "# GS Quant STS Index Tutorial"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7f178e4f",
   "metadata": {},
   "source": [
    "Welcome to the GS Quant Index tutorial!  This tutorial will walk you through using the Index class functionality in GS Quant with a focus on STS Indices.\n",
    "\n",
    "Marquee [Systematic Trading Strategy (STS)](https://marquee.gs.com/welcome/products/index-solutions/systematic-trading-strategies) offering provides a variety of information for STS Indices including prices, compositions and PnL attribution.\n",
    "GS Quant makes accessing this data via API intuitive and fast.\n",
    "\n",
    "In this tutorial, you will fetch an STS Index and learn how to:\n",
    "1. Get strategy values\n",
    "3. Get bottom level composition\n",
    "4. Get full underlier tree\n",
    "5. Get factor risk data\n",
    "2. Get fundamentals metrics\n",
    "\n",
    "\n",
    "Please ensure that you have followed the setup instructions for GS Quant mentioned [here](https://developer.gs.com/docs/gsquant/getting-started/). "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5e4f17b6",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "## Pre Requisites\n",
    "To use below functionality on **STS Indices**, your application needs to have access to the following datasets:\n",
    "1. [STSLEVELS](https://marquee.gs.com/s/developer/datasets/STSLEVELS) - Official Values of STS Indices\n",
    "2. [STS_INDICATIVE_LEVELS](https://marquee.gs.com/s/developer/datasets/STS_INDICATIVE_LEVELS) - Indicative Values of STS Indices\n",
    "3. [STS_FUNDAMENTALS](https://marquee.gs.com/s/developer/datasets/STS_FUNDAMENTALS) - Fundamental metrics of STS Indices\n",
    "4. [STS_UNDERLIER_WEIGHTS](https://marquee.gs.com/s/developer/datasets/STS_UNDERLIER_WEIGHTS) - Weights of index underliers of STS Indices\n",
    "5. [STS_UNDERLIER_ATTRIBUTION](https://marquee.gs.com/s/developer/datasets/STS_UNDERLIER_ATTRIBUTION) - Attribution of index underliers\n",
    "6. [STSCONSTITUENTS](https://marquee.gs.com/s/developer/datasets/STSCONSTITUENTS) - Bottom level index constituents and associated weights\n",
    "\n",
    "You can request access by going to the Dataset Catalog Page linked above.\n",
    "\n",
    "**Note** - If you're using GS Quant as an internal user, you need to raise the above for yourself. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8b88245b",
   "metadata": {},
   "source": [
    "# First Steps\n",
    "### 1. Authenticate & Initialize your session\n",
    "\n",
    "First you will import the necessary modules and add your client id and client secret. To checke your app's authentication, follow our [Getting Started guide.](https://developer.gs.com/docs/gsquant/authentication/gs-session/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5171db43",
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "from gs_quant.markets.index import Index\n",
    "from gs_quant.markets.indices_utils import *\n",
    "from gs_quant.data.fields import DataMeasure\n",
    "from gs_quant.session import Environment, GsSession\n",
    "\n",
    "import datetime as dt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f758e77f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# external users should substitute their client id and secret; please skip this step if using internal jupyterhub\n",
    "GsSession.use(Environment.PROD, client_id=None, client_secret=None, scopes=('read_product_data',))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4069e261",
   "metadata": {},
   "source": [
    "### 2. Fetch the index information\n",
    "\n",
    "#### Load the index\n",
    "Next you will fetch the index you'd like to work with, by passing in any of its identifiers such as Bloomberg Id, Ticker, etc.\n",
    "In this tutorial, we're using some sample STS indices:\n",
    "1. GSMBMA5S - A multi-asset strategy\n",
    "2. GSISM37E - A strategy based on single stocks\n",
    "\n",
    "To access any STS Index, your app should have access to view that index. Please note that **apps do not automatically inherit the access of their owners**. This means that your apps need to be separately granted access to the required STS Indices.\n",
    "\n",
    "To request access to the above samples, please [send an email](mailto:gs-sts-marquee-permissioning-global@gs.com?cc=gs-marquee-sts-support@gs.com&subject=Request%20to%20access%20<index%20identifier>%20via%20API&body=I%20would%20like%20to%20access%20the%20index%20<index%20identifier>%20via%20my%20app%20<app%20client%20id>) to our team mentioning your app's id.\n",
    "\n",
    "If you app already has access to some other STS indices, you can use them as well. Just replace the ticker below with the ticker of your index."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b5d12812",
   "metadata": {},
   "outputs": [],
   "source": [
    "ma_index = Index.get('GSMBMA5S') # Substitute input with the identifier for an Index\n",
    "sstk_index  = Index.get('GSISM37E')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b9ea63af",
   "metadata": {},
   "source": [
    "#### Get the Index URL on Marquee"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5bcff23b-fd83-45e8-9b36-7cb3d0d51bc2",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Retrieves the url of the product page of the index on Marquee\n",
    "ma_index.get_url()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a7580ce9",
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "start_date = dt.date(2022, 3, 1)\n",
    "end_date = dt.date(2022, 4, 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6aca8516",
   "metadata": {},
   "source": [
    "# Strategy Values of an STS Index\n",
    "\n",
    "In general, all Indices support official close prices but for STS Indices, official and indicatvive strategy values are supported. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "29b00c8b",
   "metadata": {},
   "source": [
    "The strategy values of an STS Index can be obtained by using the `get_close_prices` function. You may choose one of the following price types:\n",
    "\n",
    "**Official Strategy Values**: PriceType.OFFICIAL_PRICE <br>\n",
    "**Indicative Strategy Values**: PriceType.INDICATIVE_CLOSE_PRICE - _Currently available for STS indices only._"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dad27eeb-a6b2-4d73-8702-4d34625576b8",
   "metadata": {},
   "source": [
    "### Get Official Close Prices"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cc5ac3e0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Returns strategy values between start and end date. When no price_type is passed, it defaults to official strategy values\n",
    "ma_index.get_close_prices(start=start_date,\n",
    "                       end=end_date)\n",
    "\n",
    "# Returns official strategy values between start and end date \n",
    "sstk_index.get_close_prices(start=start_date,\n",
    "                       end=end_date,\n",
    "                       price_type=[PriceType.OFFICIAL_CLOSE_PRICE])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "66a19bca-d28b-4c1d-ad60-1d5e9b0c4e0a",
   "metadata": {},
   "source": [
    "### Get Indicative Close Prices"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cb897e4e-e5a9-4a19-adec-bafb22a198a9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Returns indicative strategy values between start and end date \n",
    "ma_index.get_close_prices(start=start_date,\n",
    "                       end=end_date,\n",
    "                       price_type=[PriceType.INDICATIVE_CLOSE_PRICE])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5ecd4b35-7d4e-4c35-9903-76c6aea3c067",
   "metadata": {},
   "source": [
    "### Get all close prices"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6b204b40-50b9-458b-b130-7ca636eebac8",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Returns official and indicative strategy values between start and end date for the STS index\n",
    "ma_index.get_close_prices(start=start_date,\n",
    "                       end=end_date,\n",
    "                       price_type=[PriceType.OFFICIAL_CLOSE_PRICE, PriceType.INDICATIVE_CLOSE_PRICE])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3236cb73-6ed7-4ba1-96c3-39836cce872f",
   "metadata": {},
   "source": [
    "# Composition Data of STS Index\n",
    "\n",
    "The composition of an STS Index can be understood as a tree structure - the index is the topmost node, and it has some child nodes.\n",
    "These child nodes can either be bottom level assets or have child nodes of their own.\n",
    "The intermediate child nodes (i.e. those which have their own children) are called **underliers**. While the bottom level assets are called **constituents**.\n",
    "\n",
    "![Tree](./images/index_composition_diagram.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0d1f82b0",
   "metadata": {},
   "source": [
    "<a id=\"constituents\"></a>\n",
    "\n",
    "### Get Constituents\n",
    "\n",
    "The constituents of an Index are the bottom level assets. Fetch the constituents of the index using the `get_constituents` method.\n",
    "\n",
    "You can also get convert the constituents of an index into Instrument objects."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "96b365a6-1dce-48e2-b3dc-ec2b078f5312",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Returns constituents of the index as a pandas DataFrame object\n",
    "sstk_index.get_constituents_for_date(date=start_date)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "16cf7e9b-470e-489c-89be-100049a2459e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Returns constituents of the index as a list of instrument class objects\n",
    "sstk_instruments = sstk_index.get_constituent_instruments_for_date(date=start_date)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bbb6eb5b",
   "metadata": {},
   "source": [
    "### Get Underlier Tree\n",
    "\n",
    "You can fetch the underlier tree of an index using the `get_underlier_tree` method. This method returns the composition tree alongwith the weights and attributions of the nodes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "31d01dda",
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "# Returns the top node of the tree structure formed by the index\n",
    "ma_index.get_underlier_tree()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b548eec0",
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "# Returns the tree structure formed by the index as a pandas dataframe\n",
    "ma_index.get_underlier_tree().to_frame()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "df0d7595-7936-4602-8fca-fd889193748b",
   "metadata": {},
   "source": [
    "We proVisualisation functions require installing the `treelib` package, so let's go ahead and install it.\n",
    "\n",
    "*Note:* This is part of GS Quant's `notebook` dependencies. You can run `pip install gs-quant[notebook]` to install all of them."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f62f6e5b-f674-4b72-a8f5-f702949fd794",
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install treelib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5c9b479f",
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "# Prints the tree structure formed by the Index for easy visualisation\n",
    "ma_index.visualise_tree(visualise_by='name')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7b8717fb",
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "# If data is missing for any field, then assetId will be used instead\n",
    "ma_index.visualise_tree(visualise_by='bbid')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8df35d26-0238-45af-bf04-dd532685f7c4",
   "metadata": {},
   "outputs": [],
   "source": [
    "ma_index.visualise_tree(visualise_by='id')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8bddb2cb",
   "metadata": {},
   "source": [
    "### Get  Underlier Weights and Attribution\n",
    "The underliers of an Index are the intermediate nodes in the composition tree.\n",
    "\n",
    "You can fetch the weights and attribution of the underliers one level down using `get_underlier_weights` and `get_underlier_attribution` methods."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b14ecab1",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Returns immediate underlier weights (one level down) as a pandas dataframe\n",
    "ma_index.get_underlier_weights()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8cdbbf43-62c8-4f9e-b486-b42d970cec58",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Returns immediate underlier attribution (one level down) as a pandas dataframe\n",
    "ma_index.get_underlier_attribution()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d1c35b26",
   "metadata": {},
   "source": [
    "# Fundamental Metrics of STS Index"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c76799d2",
   "metadata": {},
   "source": [
    "Single Stock STS Indices offer Fundamental Metrics data via API, which can be obtained using the `get_fundamentals` function.\n",
    "\n",
    "You may choose one of the following periods:\n",
    "\n",
    "- **1 year:** DataMeasure.ONE_YEAR\n",
    "- **2 years:** DataMeasure.TWO_YEARS\n",
    "- **3 years:** DataMeasure.THREE_YEARS\n",
    "\n",
    "You may choose one of the following period directions:\n",
    "\n",
    "- **Forward:** DataMeasure.FORWARD\n",
    "- **Trailing:** DataMeasure.TRAILING\n",
    "\n",
    "You may choose any combination of the following metrics:\n",
    "\n",
    "- **Dividend Yield:** DataMeasure.DIVIDEND_YIELD\n",
    "- **Earnings per Share:** DataMeasure.EARNINGS_PER_SHARE\n",
    "- **Earnings per Share Positive:** DataMeasure.EARNINGS_PER_SHARE_POSITIVE\n",
    "- **Net Debt to EBITDA:** DataMeasure.NET_DEBT_TO_EBITDA\n",
    "- **Price to Book:** DataMeasure.PRICE_TO_BOOK\n",
    "- **Price to Cash:** DataMeasure.PRICE_TO_CASH\n",
    "- **Price to Earnings:** DataMeasure.PRICE_TO_EARNINGS\n",
    "- **Price to Earnings Positive:** DataMeasure.PRICE_TO_EARNINGS_POSITIVE\n",
    "- **Price to Sales:** DataMeasure.PRICE_TO_SALES\n",
    "- **Return on Equity:** DataMeasure.RETURN_ON_EQUITY\n",
    "- **Sales per Share:** DataMeasure.SALES_PER_SHARE"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "92be04e7",
   "metadata": {},
   "source": [
    "### Get Fundamentals"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7899fcb1",
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "# Returns fundamentals data between start and end date for the STS index\n",
    "sstk_index.get_fundamentals(start=start_date, end=end_date)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "45d2bce5-df5a-4ce9-a7d1-a35da7685db3",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Returns fundamentals data between start and end date for the STS index for one year period with trailing direction and Price to Cash metric\n",
    "sstk_index.get_fundamentals(start=start_date,\n",
    "                       end=end_date,\n",
    "                       period=DataMeasure.ONE_YEAR,\n",
    "                       direction=DataMeasure.TRAILING,\n",
    "                       metrics=[DataMeasure.PRICE_TO_CASH, DataMeasure.SALES_PER_SHARE])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3b52580e",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "### You're all set, Congrats!\n",
    "\n",
    "*Have any other questions? Reach out to the [Marquee STS team](mailto:gs-marquee-sts-support@gs.com)!*"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
